<?php
namespace app\api\model\food;

use app\api\model\CouponUser;
use app\api\model\Setting;
use app\api\model\Shop;
use think\facade\Cache;
use hema\Helper;
use hema\wechat\Driver;
use hema\wechat\Map;


/**
 * 购物车管理
 */
class Cart
{
    public $error = '';	//错误信息
    private $table_id;
    private $user_id;	//用户id
	private $shop_id;	//门店id
    private $applet_id;   //模板id
    private $cart = [];	//购物车列表
    private $clear = false;	//是否清空购物车

    /**
     * 构造方法
     */
    public function __construct($user_id, $shop_id, $applet_id,$table_id='')
    {
        $this->user_id = $user_id;
        $this->table_id = $table_id;
		$this->shop_id = $shop_id;
        $this->applet_id = $applet_id;
        if(empty($table_id)){
            $title = $user_id;
        }else{
            $title = $table_id;
        }
        $this->cart = Cache::get('cart_' . $title . '_' . $this->shop_id) ?: [];
    }
	
	 /**
     * 获取购物车内容
     */
    public function getCart()
    {
		return $this->cart;
	}

    public function getList($user, $order_mode = 0, $coupon_user_id = 0)
    {
        // 商品列表
        $goodsList = [];
        $goodsIds = array_unique(array_column($this->cart, 'goods_id'));
        foreach ((new Goods)->getListByIds($goodsIds) as $goods) {
            $goodsList[$goods['goods_id']] = $goods;
        }
        // 是否存在收货地址
        sizeof($user['address']) > 0 ? $exist_address = true : $exist_address = false;
        $pack_price = 0;//餐盒费
        // 购物车商品列表
        $cartList = [];
        foreach ($this->cart as $key => $cart) {
            // 判断商品不存在则自动删除
            if (!isset($goodsList[$cart['goods_id']])) {
                $this->delete($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
            $goods = clone $goodsList[$cart['goods_id']];
            // 商品sku信息
            $goods['goods_sku_id'] = $cart['goods_sku_id'];
            // 商品sku不存在则自动删除
            if (!$goods['goods_sku'] = $goods->getGoodsSku($cart['goods_sku_id'])) {
                $this->delete($cart['goods_id'], $cart['goods_sku_id']);
                continue;
            }
            // 判断商品是否下架
            if ($goods['goods_status']['value'] != 10) {
                $this->setError('很抱歉，商品 [' . $goods['goods_name'] . '] 已下架');
            }
            //计算餐盒费
			if($order_mode == 20 OR $order_mode == 30){
				if($goods['pack_price']>0){
					$pack_price = $pack_price + $goods['pack_price']*$cart['goods_num'];
				}
			}
			// 商品单价
			$goods['goods_price'] = $goods['goods_sku']['goods_price'];
			// 商品总价
			$goods['total_num'] = $cart['goods_num'];
			$goods['total_price'] = $total_price = bcmul($goods['goods_price'], $cart['goods_num'], 2);
            $cartList[] = $goods->hidden(['category', 'content', 'spec']);
        }
        // 商品总金额
        $orderTotalPrice = Helper::getArrayColumnSum($cartList, 'total_price');
	    $order_pay_price = $orderTotalPrice;
		// 订单配送费用
        $expressPrice = 0;
		$min_price = 0;
		//餐盒费加入总价
		if($pack_price>0){
			$order_pay_price = $order_pay_price + $pack_price;
		}
		// 商品是否在配送范围
        $intraRegion = true;
		//如果是外卖 +配送费用
		//获取配送设置
        $delivery = Setting::getItem('delivery');
		if($order_mode==20){
			if($user['address_default']){
				//如果免费派送范围大于0
				$shop = Shop::get($this->shop_id);
                $map = new Map;
                //计算距离
				if($result = $map->getDistance($shop['coordinate'],$user['address_default']['location'])){
					$distance = $result[0]['distance'];//获取距离计算结果
					if($delivery['delivery_range'] < $distance){
						$intraRegion = false;
					}
					if($delivery['free_range']>0){
						if($delivery['free_range'] < $distance){ //如果超出免费区域就增加配送费
							$expressPrice = $delivery['delivery_price'];
							$order_pay_price = $order_pay_price + $expressPrice;
						}
					}else{
						$expressPrice = $delivery['delivery_price'];
						$order_pay_price = $order_pay_price + $expressPrice;
					}
				}else{//定位错误加配送费
					$expressPrice = $delivery['delivery_price'];
					$order_pay_price = $order_pay_price + $expressPrice;
					$this->setError($map->getError());
				}
			}			
		}
		//计算最低配送价格范围
		if($orderTotalPrice<$delivery['min_price']){
			$min_price = $delivery['min_price'] - $orderTotalPrice;					
		}

        $order = [
            'coupon_list' => [], //优惠券列表
            'goods_list' => $cartList,                       // 商品列表
            'order_total_num' => $this->getTotalNum(),       // 商品总数量
            'order_total_price' => Helper::number2($orderTotalPrice),              // 商品总金额 (不含运费)
            'order_pay_price' => Helper::number2($order_pay_price),    // 实际支付金额
			'activity_price' => Helper::number2(0),	// 优惠金额
			'min_price' => $min_price,	// 起送价价
			'pack_price' => Helper::number2($pack_price),	// 餐盒费用
            'address' => $user['address_default'],  // 默认地址
            'exist_address' => $exist_address,      // 是否存在收货地址
            'express_price' => Helper::number2($expressPrice),       // 配送费用
            'intra_region' => $intraRegion,         // 当前用户收货城市是否存在配送规则中
            'has_error' => $this->hasError(),
            'error_msg' => $this->getError(),
        ];
        //获取优惠券列表
        $coupon_type = 0;
        $order_mode != 20 && $coupon_type = 10;
        $coupon_list = (new CouponUser)->getList($this->user_id,$coupon_type,$this->shop_id);
        if($coupon_list){
            $order = $this->checkCoupon($coupon_list,$order);
        }
        if($coupon_list AND $coupon_user_id > 0){
            $coupon = CouponUser::get($coupon_user_id,['coupon']);
            $order = $this->useCoupon($coupon,$order);
        }
        return $order;        
    }

    /**
     * 使用优惠券
     */
    private function useCoupon($coupon,$order)
    {
        //现金券验证
        if($coupon['type']['value'] == 10){
            //1立减 ={money=金额}
            //2首单减 = {money=金额}
            $price = (float)$coupon['coupon']['values']['money'];
            $order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
            $order['activity_price'] = Helper::number2($price); // 优惠金额
        }
        //折扣券
        if($coupon['type']['value'] == 20){
            //6等级折扣 ={ lv=等级 0不限,discount = 折扣 }
            $price = $order['order_total_price'] - $order['order_total_price'] * (float)$coupon['coupon']['values']['discount'] / 100; //计算优惠金额
            $order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
            $order['activity_price'] = Helper::number2($price); // 优惠金额
        }
        //满赠券
        if($coupon['type']['value'] == 30){
            //3满赠 = { condition=满足数值条件 {10金额 20数量} num = 数值 type = 赠品类型 {10优惠券 20商品} gift = 礼物{ id=编号 name=名称 image=图片 }
            $order['gift'] = $coupon['coupon']['values']['gift'];
        }
        //减免券
        if($coupon['type']['value'] == 40){
            //4满减 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 } 
            //5满折 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 } 
            if($coupon['coupon']['values']['condition'] == 10){
                //按照订单总金额
                if($coupon['coupon']['mode'] == 4){
                    //满减
                    $price = (float)$coupon['coupon']['values']['money']; //计算优惠金额
                }else{
                    //满折
                    $price = $order['order_total_price'] - $order['order_total_price'] * (float)$coupon['coupon']['values']['money'] / 100; //计算优惠金额
                }
                $order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
                $order['activity_price'] = Helper::number2($price); // 优惠金额
            }else{
                for($x=0;$x<sizeof($order['goods_list']);$x++){
                    //按照数量
                    if($order['goods_list'][$x]['total_num'] >= $coupon['coupon']['values']['num']){
                        if($coupon['coupon']['mode'] == 4){
                            //满减
                            $price = (float)$coupon['coupon']['values']['money']; //计算优惠金额
                            $order['goods_list'][$x]['active'] = '满减';
                        }else{
                            //满折
                            $price = $order['goods_list'][$x]['goods_sku']['goods_price'] - $order['goods_list'][$x]['goods_sku']['goods_price'] * (float)$coupon['coupon']['values']['money'] / 100; //计算优惠金额
                            $order['goods_list'][$x]['active'] = '满折';
                        }
                        $order['order_pay_price'] = Helper::number2($order['order_pay_price'] - $price);// 实际支付金额
                        $order['activity_price'] = Helper::number2($price); // 优惠金额
                        break;
                    }
                }
            }
        }
        if($order['order_pay_price'] < 0){
            $order['order_pay_price'] = Helper::number2(0);
        }
        return $order;
    }

    /**
     * 验证优惠券是否可用
     */
    private function checkCoupon($list,$order)
    {
        $coupon_list = [];
        for($n=0;$n<sizeof($list);$n++){
            $item = $list[$n]->toArray();
            unset($item['user']);
            //现金券验证
            if($item['type']['value'] == 10){
                //1立减 ={money=金额}
                if($item['coupon']['mode'] == 1){
                    array_push($coupon_list,$item);
                }
                //2首单减 = {money=金额}
                if($item['coupon']['mode'] == 2){
                    $orderCount = (new Order)->where(['user_id' => $this->user_id])->count();
                    if($orderCount == 0){
                        array_push($coupon_list,$item);
                    }
                }
            }
            //折扣券
            if($item['type']['value'] == 20){
                //6等级折扣 ={ lv=等级 0不限,discount = 折扣 }
                if($item['coupon']['values']['lv'] == 0){
                    array_push($coupon_list,$item);
                }else{
                    //获取用户详情
                    $user = UserModel::get($this->user_id);
                    if($user['v'] == $item['coupon']['values']['lv']){
                        array_push($coupon_list,$item);
                    }
                }
            }
            //满赠券
            if($item['type']['value'] == 30){
                //3满赠 = { condition=满足数值条件 {10金额 20数量} num = 数值 type = 赠品类型 {10优惠券 20商品} gift = 礼物{ id=编号 name=名称 image=图片 }
                if($item['coupon']['values']['condition'] == 10){
                    //按照金额
                    if($order['order_total_price'] >= $item['coupon']['values']['num']){
                        array_push($coupon_list,$item);
                    }
                }else{
                    //按照数量
                    if($order['order_total_num'] >= $item['coupon']['values']['num']){
                        array_push($coupon_list,$item);
                    }
                }
            }
            //减免券
            if($item['type']['value'] == 40){
                //4满减 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 } 
                //5满折 = { condition=满足数值条件 {10金额 20数量} num = 数量值 money = 减/折数值 } 
                if($item['coupon']['values']['condition'] == 10){
                    //按照订单总金额
                    if($order['order_total_price'] >= $item['coupon']['values']['num']){
                        array_push($coupon_list,$item);
                    }
                }else{
                    foreach ($order['goods_list'] as $vo) {
                        //按照单品数量
                        if($vo['total_num'] >= $item['coupon']['values']['num']){
                            array_push($coupon_list,$item);
                            break;
                        }
                    }
                }
            }
        }
        $order['coupon_list'] = $coupon_list;
        return $order;
    }

    /**
     * 添加购物车
     */
    public function add($data)
    {
        // 购物车商品索引
        $index = $data['goods_id'] . '_' . $data['goods_sku_id'];
        // 商品信息
        $goods = Goods::detail($data['goods_id']);
        // 商品sku信息
        $goods['goods_sku'] = $goods->getGoodsSku($data['goods_sku_id']);
        // 判断商品是否下架
        if ($goods['goods_status']['value'] != 10) {
            $this->setError('很抱歉，该商品已下架');
            return false;
        }
        // 判断商品库存
        $cartGoodsNum = $data['goods_num'] + (isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] : 0);
        $data['create_time'] = time();
        if (sizeof($this->cart) == 0) {
            $this->cart[$index] = $data;
            return true;
        }
        isset($this->cart[$index]) ? $this->cart[$index]['goods_num'] = $cartGoodsNum : $this->cart[$index] = $data;
        return true;
    }

    /**
     * 减少购物车中某商品数量
     */
    public function sub($data)
    {
        $index = $data['goods_id'] . '_' . $data['goods_sku_id'];
        if($this->cart[$index]['goods_num'] > 1 ){
            $this->cart[$index]['goods_num']--;
        }elseif($this->cart[$index]['goods_num'] == 1){
            unset($this->cart[$index]);
        }
    }

    /**
     * 删除购物车中指定商品
     */
    public function delete($data)
    {
        //为空是商城批量删除
        if(empty($data['goods_id'])){
            $indexArr = strpos( $data['goods_sku_id'], ',') !== false ? explode(',',  $data['goods_sku_id']) : [ $data['goods_sku_id']];
            foreach ($indexArr as $index) {
                if (isset($this->cart[$index])) unset($this->cart[$index]);
            }
        }else{
            $index = $data['goods_id'] . '_' . $data['goods_sku_id'];
            if (isset($this->cart[$index])) unset($this->cart[$index]);
        }
    }

    /**
     * 获取当前用户购物车商品总数量
     */
    public function getTotalNum()
    {
        return array_sum(array_column($this->cart, 'goods_num'));
    }

    /**
     * 析构方法
     * 将cart数据保存到缓存文件
     */
    public function __destruct()
    {
        if(empty($this->table_id)){
            $title = $this->user_id;
        }else{
            $title = $this->table_id;
        }
        $this->clear !== true && Cache::set('cart_' . $title . '_' . $this->shop_id, $this->cart, 86400);
    }

    /**
     * 清空当前用户购物车
     */
    public function clearAll()
    {
        $this->clear = true;
        if(empty($this->table_id)){
            $title = $this->user_id;
        }else{
            $title = $this->table_id;
        }
        Cache::delete('cart_' . $title . '_' . $this->shop_id);
    }

    /**
     * 设置错误信息
     */
    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    /**
     * 是否存在错误
     */
    private function hasError()
    {
        return !empty($this->error);
    }

    /**
     * 获取错误信息
     */
    public function getError()
    {
        return $this->error;
    }

}
